#!/usr/bin/ruby
#-*- coding: UTF-8 -*-
require 'xcodeproj'
Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8
xcodeProjPath = ARGV[0]
project_path = xcodeProjPath
$platform_project = Xcodeproj::Project.open(project_path)
#confusion.plist和本脚本要在同一目录
confusion_plist_path = "#{File.dirname(__FILE__)}/confusion.plist"
$confusion_hash = Xcodeproj::Plist.read_from_path(confusion_plist_path)
$replace_hash = Hash.new

def get_rand_str (str_len)
	azAZ = ("a".."z").to_a + ("A".."Z").to_a
	rand_str = ""
	str_len.times do
		rand_str << azAZ.sample
	end
	rand_str
end

def get_method_name_array (mothod_str)
	if mothod_str.include? ":"
		return mothod_str.scan(/\b\w+:/)
	else
		temp_str = mothod_str.scan(/\b\w+\b/).last
		return Array.new(1) {temp_str}
	end
end

def buildReplaceHash
	$confusion_hash.each{|key,value|
		if value["changeClassName"]
			$replace_hash[key] = get_rand_str rand(3..15)
		end
		if value.class.to_s == "Hash"
			method_array = value["functionArray"]
			method_array.each{|array_parameter|
				method_str_array = get_method_name_array array_parameter
				method_str_array.each{|replace_key|
					tem_value = get_rand_str rand(3..15)
					if replace_key.include? ":"
						tem_value = tem_value + ":"
					end
					$replace_hash[replace_key] = tem_value
				}
			}
		end
	}
end

def changeFileName (file_reference_to_change)
	file_name = file_reference_to_change.path.split(".").first
	if $confusion_hash.has_key?(file_name)
		if $confusion_hash[file_name]["changeClassName"]
			new_file_name = $replace_hash[file_name]
			new_file_path = file_reference_to_change.path.gsub(file_name,new_file_name)

			real_path = file_reference_to_change.real_path
			new_real_path = real_path.to_s.gsub(file_name,new_file_name)

			File::rename(real_path,new_real_path)
			file_reference_to_change.path = new_file_path
		end
	end
end

def build_scan_reg (parameter_array)
	reg_str = "/\\b#{parameter_array.first}"
	count = parameter_array.size - 1
	
	if count == 0 and ! parameter_array.first.to_s.include? ":"
		reg_str = reg_str + "\\b/"
		return Regexp.new reg_str[1..-2]
	else
		if count != 0
			for i in 1..count
				reg_str = reg_str + ".\*\\b#{parameter_array[i]}"
			end
		end
		reg_str = reg_str + "/"
		return Regexp.new reg_str[1..-2]
	end
end

def build_replace_reg (parameter_array)
	count = parameter_array.size
	if count == 1
		reg_str = "/\\b#{parameter_array.first}/"
		return Regexp.new reg_str[1..-2]
	else
		reg_str = "/\\b(#{parameter_array.first}"
		for i in 1..(count - 1)
			reg_str = reg_str + "|\\b#{parameter_array[i]}"
		end
		reg_str = reg_str + ")/"
		return Regexp.new reg_str[1..-2]
	end
end

def change_method_in_file (file_reference_to_modify)
	file_content = File.new(file_reference_to_modify.real_path, "r").read()
	$confusion_hash.each{|key,value|
		if file_content.include? key
			key_reg_str = "/\\b#{key}\\b/"
			key_scan_reg = Regexp.new key_reg_str[1..-2]
			key_contain_array = file_content.scan(key_scan_reg)
			if !key_contain_array.empty?
				method_array = value["functionArray"]
				method_array.each{|array_parameter|
					method_str_array = get_method_name_array array_parameter
					method_str_scan_reg = build_scan_reg method_str_array
					method_str_replace_reg = build_replace_reg method_str_array
					#puts method_str_scan_reg
					#puts method_str_replace_reg
					file_content = file_content.gsub(method_str_scan_reg){|match_method|
						#puts "match method start#{match_method}end"
						new_method_str = match_method.gsub(method_str_replace_reg){|to_replace_method_str|
							if $replace_hash.has_key?(to_replace_method_str)
								$replace_hash[to_replace_method_str]
							else
								to_replace_method_str
							end
						}
						#puts "new start#{new_method_str}end"
						new_method_str
					}
				}
			end
			if $replace_hash.has_key?(key) and value["changeClassName"]
				file_content = file_content.gsub(key_scan_reg,$replace_hash[key])
			end
		end
	}
	write_file = File.new(file_reference_to_modify.real_path, "w+")
	if write_file
   		write_file.syswrite(file_content)
	end
end

def get_file_reference
	file_reference_array = Array.new(0)
	# 获得文件目录并修改plish文件
	#platform_target = $platform_project.targets[0]
	#main_group_path = $platform_project.main_group.real_path
	main_group_children_array = $platform_project.main_group.children
	main_group_children_array.each do |main_children_file|
		if "#{main_children_file.path}" == "ios"
			#puts "ios"
			# puts main_children_file.class
	 		ios_file = main_children_file
	 		ios_file.children.each do |ios_file_reference|
	 			if ios_file_reference.path.to_s == "sdk"
	 				ios_file_reference.children.each do |sdk_file_reference|
	 					# puts sdk_file_reference.path
	 					# changeFileName sdk_file_reference
	 					file_reference_array.push(sdk_file_reference)
	 				end
	 			end
	 			if ios_file_reference.path.to_s == "jooyuusdk"
	 				ios_file_reference.children.each do |jooyuusdk_file_reference|
	 					# puts jooyuusdk_file_reference.path
	 					# changeFileName jooyuusdk_file_reference
	 					file_reference_array.push(jooyuusdk_file_reference)
	 				end
	 			end
	 			if ios_file_reference.class.to_s == "Xcodeproj::Project::Object::PBXFileReference"
	 				# changeFileName ios_file_reference
	 				file_reference_array.push(ios_file_reference)
	 			end
	 		end
		end
		if "#{main_children_file.path}" == "sdk"
			#puts "ios"
			# puts main_children_file.class
	 		sdk_file = main_children_file
	 		sdk_file.children.each do |sdk_file_reference|
	 			if sdk_file_reference.path.to_s == "iOSFusionSDK"
	 				sdk_file_reference.children.each do |fusion_sdk_file_reference|
	 					# puts sdk_file_reference.path
	 					# changeFileName sdk_file_reference
	 					file_reference_array.push(fusion_sdk_file_reference)
	 				end
	 			end
	 		end
		end
	end
	return file_reference_array
end
#生成混淆替换的对应关系
buildReplaceHash
puts $replace_hash
#获取所有文件索引
file_array = get_file_reference
file_array.each do |file|
	change_method_in_file file
end
file_array.each do |file|
	changeFileName file
end

puts "save modify"
$platform_project.save